package br.elsa.survey.view.beans.managed.tests;

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.List;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import br.elsa.survey.domain.questions.CheckboxOption;
import br.elsa.survey.domain.questions.CheckboxQuestion;
import br.elsa.survey.domain.questions.QuestionsFactory;
import br.elsa.survey.services.QuestionService;
import br.elsa.survey.view.beans.managed.CheckboxQuestionCreationView;
import br.elsa.survey.view.messages.ViewMessages;

/**
 * TDD test class for {@link CheckboxQuestionCreationView}
 * 
 * @author diego
 * @since 2010-10-03
 */
public class CheckboxQuestionCreationViewControllerTest {

	/**
	 * Class under test
	 */
	private CheckboxQuestionCreationView viewHandler;

	@Mock
	private QuestionService questionService;

	@Mock
	private CheckboxQuestion newQuestion;

	@Mock
	private QuestionsFactory factory;

	@Mock
	private ViewMessages viewMessages;

	@Before
	public void setUp() throws Exception {
		MockitoAnnotations.initMocks(this);
		this.viewHandler = new CheckboxQuestionCreationView(newQuestion, factory, questionService, viewMessages);
	}

	@Test
	public void addNewOptionShouldCallQuestionService() {

		viewHandler.addNewOption();
		verify(newQuestion, times(1)).createNewEmptyOption();
	}

	@Test
	public void removeLastOptionJustIfOptionsSizeIsGreaterThanOne() {

		List<CheckboxOption> optionsSizeTwo = mock(List.class);

		when(optionsSizeTwo.size()).thenReturn(2);
		when(newQuestion.getOptions()).thenReturn(optionsSizeTwo);

		viewHandler.removeLastChoice();
		verify(newQuestion, times(1)).removeLastOption();
	}

	@Test
	public void removeLastOptionShouldNotRemoveAnOptionIfOptionsSizeIsLesserThanTwo() {

		List<CheckboxOption> optionsSizeOne = mock(List.class);

		when(optionsSizeOne.size()).thenReturn(1);
		when(newQuestion.getOptions()).thenReturn(optionsSizeOne);

		viewHandler.removeLastChoice();
		verify(newQuestion, never()).removeLastOption();
	}

	@Test
	public void resetComponentShoudResetNewComponentState() {
		CheckboxQuestion resetedQuestion = mock(CheckboxQuestion.class);
		when(factory.createCheckboxQuestion()).thenReturn(resetedQuestion);

		viewHandler.resetViewState();

		Assert.assertEquals(resetedQuestion, viewHandler.getNewQuestion());
	}

	@Test
	public void minNumberChosenOptionsShouldNotBeGreaterThanOptionsCount() {
		List<CheckboxOption> options = mock(List.class);

		when(newQuestion.getMinNumberChosenOptions()).thenReturn(5);
		when(newQuestion.getOptions()).thenReturn(options);
		when(options.size()).thenReturn(4);

		viewHandler.createQuestion();

		verify(viewMessages, times(1)).addErrorMessage(anyString());
	}

	@Test
	public void minNumberChosenOptionsCanBeEqualsToOptionsCount() {
		List<CheckboxOption> options = mock(List.class);

		when(newQuestion.getMinNumberChosenOptions()).thenReturn(4);
		when(newQuestion.getOptions()).thenReturn(options);
		when(options.size()).thenReturn(4);

		viewHandler.createQuestion();

		verify(viewMessages, never()).addErrorMessage(anyString());
	}
}
